package com.swpu.service_step.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.swpu.commonutils.HttpClientUtils;
import com.swpu.commonutils.R;
import com.swpu.service_drink.entity.vo.DrinkRecordChartDataVo;
import com.swpu.service_step.entity.StepDecryptDayData;
import com.swpu.service_step.entity.StepRecord;
import com.swpu.service_step.entity.WxAuthorizeVo;
import com.swpu.service_step.mapper.StepRecordMapper;
import com.swpu.service_step.service.StepRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.swpu.service_step.service.StepTargetService;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chaichai
 * @since 2024-03-03
 */
@Service
public class StepRecordServiceImpl extends ServiceImpl<StepRecordMapper, StepRecord> implements StepRecordService {
    @Autowired
  private StepTargetService stepTargetService;
    @Value("${wx.appid}")
    private String appid;
    @Value("${wx.appsecret}")
    private String appsecret;

    @Override
    public R decodeData(WxAuthorizeVo wxAuthorizeVo) throws Exception {
        if(wxAuthorizeVo.getCode().equals("")){
            return R.error();
        }
        String openIdAndSessionKey = this.getOpenIdAndSessionKey(wxAuthorizeVo);    //获取微信运动中心加密的用户运动数据
        JSONObject jsonObject = JSON.parseObject(openIdAndSessionKey);
        String sessionKey = (String) jsonObject.get("session_key");
        String openid = (String) jsonObject.get("openid");
        if (sessionKey==null) return R.error().message("获取用用户信息失败");
        String decrypt = decryptWeChatRunInfo(sessionKey, wxAuthorizeVo.getEncryptedData(), wxAuthorizeVo.getIv());    //解密数据
        JSONObject stepInfoListJson = JSON.parseObject(decrypt);
        //解析json，获取stepInfoList下面的步数
        List<StepDecryptDayData> stepInfoList = JSON.parseArray(stepInfoListJson.getString("stepInfoList"), StepDecryptDayData.class);
        System.out.println(stepInfoList);
        Date fromDate = DateUtil.beginOfDay(new Date(stepInfoList.get(0).getTimestamp()*1000));
        Date toDate = DateUtil.endOfDay(new Date(stepInfoList.get(stepInfoList.size() - 2).getTimestamp()*1000L));
        //以下为同步除今天之前的微信步数数据
        List<StepRecord> stepRecords = baseMapper.queryRecordByDate(openid, fromDate, toDate);
        ArrayList<Date> dates = new ArrayList<>();
        for (StepRecord stepRecord : stepRecords) {
            if(stepRecord.getRecordTime()!=null)
            dates.add(DateUtil.beginOfDay(stepRecord.getRecordTime()));
        }
        ArrayList<StepRecord> stepRecordListAdd = new ArrayList<>();
        int index=0;
        Date dateTemp=fromDate;
        while (dateTemp.before(toDate)){
            if (index==28){
                int a=0;
            }
            boolean isHave=false;
            for (Date date : dates) {      //判断今天是否已经同步过步数数据
                if (date.getTime()==dateTemp.getTime()){
                    isHave=true;
                    break;
                }
            }
            if(!isHave){          //当天数据不存在
                StepRecord stepRecord = new StepRecord();
                stepRecord.setRecordTime(dateTemp);
                stepRecord.setStepCount(stepInfoList.get(index).getStep());
                stepRecord.setUserId(openid);
                stepRecordListAdd.add(stepRecord);
            }
            dateTemp = DateUtil.offsetDay(dateTemp,1);
            index++;
        }
        if(stepRecordListAdd.size()>0){
            boolean isSave = this.saveBatch(stepRecordListAdd);
            if(!isSave) throw new RuntimeException("同步保存用户今天以前的步数失败");
        }
        StepRecord todayStep = this.updateTodayStep(openid, stepInfoList);    //已存在则更新最新的步数数据
        return R.ok().data("todayStep",todayStep);
    }

    @Override
    public StepRecord getStepsByDate(String openid, DateTime queryDate) {
        LambdaQueryWrapper<StepRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StepRecord::getUserId,openid).between(StepRecord::getRecordTime,DateUtil.beginOfDay(queryDate),DateUtil.endOfDay(queryDate));
       return this.getOne(queryWrapper);

    }

    //    获取微信用户登录openId和sessionKey
    public String getOpenIdAndSessionKey( WxAuthorizeVo wxAuthorizeVo) throws Exception {
        String res = HttpClientUtils.get("https://api.weixin.qq.com/sns/jscode2session?appid=" + this.appid + "&secret=" + this.appsecret + "&js_code=" + wxAuthorizeVo.getCode() + "&grant_type=authorization_code");
        System.out.println(res);
        return res;
    }

    public StepRecord updateTodayStep(String openid,List<StepDecryptDayData> stepInfoList){
        //今天的最新的微信步数
        StepDecryptDayData stepDecryptDayData = stepInfoList.get(stepInfoList.size() - 1);
        Date today = new Date(stepDecryptDayData.getTimestamp() * 1000);
        LambdaQueryWrapper<StepRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StepRecord::getUserId,openid).between(StepRecord::getRecordTime,DateUtil.beginOfDay(today),DateUtil.endOfDay(today));
        StepRecord todayStepData = this.getOne(queryWrapper);
        if (todayStepData==null){
            //保存今天的步数数据
            StepRecord stepRecord = new StepRecord();
            stepRecord.setStepCount(stepDecryptDayData.getStep());
            stepRecord.setUserId(openid);
            stepRecord.setRecordTime(new Date());
            this.save(stepRecord);
            return stepRecord;
        }
        if(todayStepData.getStepCount()<stepDecryptDayData.getStep()){
            todayStepData.setStepCount(stepDecryptDayData.getStep());
            this.update(todayStepData,queryWrapper);
        }
        return todayStepData;
    }

    public static String decryptWeChatRunInfo(String sessionKey, String encryptedData, String iv) {
        String result = null;
        byte[] encrypData = Base64.decodeBase64(encryptedData);
        byte[] ivData = Base64.decodeBase64(iv);
        byte[] sessionKeyB = Base64.decodeBase64(sessionKey);
        try {
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] doFinal = cipher.doFinal(encrypData);
            result = new String(doFinal);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

}
